home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / files.swg / 0080_Buffered File I-O.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-11-22  |  11.2 KB  |  480 lines

  1.  
  2. {Buffered FIle I/O - Slightly re-written, and a few code tweaks}
  3.  
  4. Unit WGBFile; {Buffered File Object Unit}
  5.  
  6. {$I WGDEFINE.INC}  { SEE WGFFIND.PAS for this include }
  7.  
  8. Interface
  9.  
  10. Const
  11. {filemode types}
  12.    fmReadOnly=0;
  13.    fmWriteOnly=1;
  14.    fmReadWrite=2;
  15.    fmDenyAll=16;
  16.    fmDenyWrite=32;
  17.    fmDenyRead=48;
  18.    fmDenyNone=64;
  19.    fmNoInherit=128;
  20.  
  21. Type
  22.    FBufType = Array[0..$fff0] of Byte;
  23.  
  24.    FFileObj = Object
  25.       BufFile: File;             {File to be buffered}
  26.       Buf: ^FBufType;            {Pointer to the buffer-actual size given by
  27. init}      BufStart: LongInt;         {File position of buffer start}
  28.       BufSize: LongInt;          {Size of the buffer}
  29.       BufChars: Word;            {Number of valid characters in the buffer}
  30.       CurrSize: LongInt;         {Current file size}
  31.       NeedWritten: Boolean;      {Buffer dirty/needs written flag}
  32.       IsOpen: Boolean;           {File is currently open flag}
  33.       CurrPos: LongInt;          {Current position in file/buffer}
  34.       MyIOResult:Word;           {= Last IOResult!}
  35.       Constructor Init(BSize:Word);
  36.       Destructor Done; Virtual;
  37.       Procedure Open(FName:String;FMode:Word); Virtual;
  38.       Procedure Create(FName:String;FMode:Word); Virtual;
  39.       Procedure CloseFile; Virtual;
  40. {      Function  EraseFile; Virtual;
  41.       Function  TruncateFile; Virtual;}
  42.       Procedure BlkRead(Var V;Num:Word;Var NumRead:Word); Virtual;
  43.       Procedure BlkWrite(Var V;Num:Word;Var NumWrite:Word); Virtual;
  44.       Procedure SeekFile(FP:LongInt); Virtual;
  45.       Function  RawSize:LongInt; Virtual;
  46.       Function  FilePos:LongInt; Virtual;
  47. {internal!}
  48.       Function  WriteBuffer:Boolean;
  49.       Function  ReadBuffer:Boolean;
  50.   End;
  51.  
  52.  
  53. Implementation
  54.  
  55. Uses
  56. {$IFDEF WINDOWS}
  57.   WinDos;
  58. {$ELSE}
  59.   Dos,
  60.   {$IFDEF OPRO}
  61.   OpCrt;
  62.   {$ELSE}
  63.   Crt;
  64.   {$ENDIF}
  65. {$ENDIF}
  66.  
  67.  
  68. Constructor FFileObj.Init(BSize:Word);
  69. Begin
  70.    Buf:=Nil;
  71.    GetMem(Buf,BSize);
  72.    MyIOResult:=1;
  73.    If Buf=Nil Then Fail;
  74.    BufSize:=BSize;
  75.    BufStart:=0;
  76.    BufChars:=0;
  77.    IsOpen:=False;
  78.    NeedWritten:=False;
  79.    CurrPos:=0;
  80.    MyIOResult:=0;
  81. End;
  82.  
  83. Destructor FFileObj.Done;
  84. Begin
  85.    If IsOpen Then CloseFile;
  86.    If Buf<>Nil Then FreeMem(Buf,BufSize);
  87. End;
  88.  
  89. Procedure FFileObj.Open(FName:String;FMode:Word);
  90. Var
  91.    Xyz:Word;
  92.  
  93. Procedure ShExist;
  94. Var
  95. {$IFDEF WINDOWS}
  96.    SR: TSearchRec;
  97.    TStr: Array[0..128] of Char;
  98. {$ELSE}
  99.    SR: SearchRec;
  100. {$ENDIF}
  101.  
  102. Begin
  103.    If IoResult <> 0 Then;
  104.    MyIOResult:=0;
  105. {$IFDEF WINDOWS}
  106.    StrPCopy(TStr,FName);
  107.    FindFirst(TStr,faReadOnly+faHidden+faArchive,SR);
  108. {$ELSE}
  109.    FindFirst(FName,SysFile+ReadOnly+Hidden+Archive,SR);
  110. {$ENDIF}
  111.    MYIoResult:=DosError;
  112. End;
  113.  
  114. Procedure shReset;
  115. Var
  116.    Count: Word;
  117.  
  118. Begin
  119.    Count:=5;
  120.    MyIOResult:=5;
  121.    While ((Count>0) and (MyIOResult=5)) Do Begin
  122.       Reset(BufFile,1);
  123.       MyIOResult:=IoResult;
  124.       Dec(Count);
  125.       If MyIOResult<>0 then Delay(180);
  126.    End;
  127. End;
  128.  
  129. Begin
  130.    If IoResult<>0 Then;
  131.    MyIOResult:=0;
  132.    If IsOpen Then CloseFile;
  133.    If MyIOResult=0 Then ShExist;
  134.    If MyIOResult=0 Then Begin
  135.       Xyz:=FileMode;
  136.       FileMode:=FMode;
  137.       Assign(BufFile,FName);
  138.       shReset;
  139.       FileMode:=Xyz;
  140.    End;
  141.    If MyIOResult=0 then Begin
  142.       IsOpen:=True;
  143.       CurrPos:=0;            {Initialize file position}
  144.       BufStart:=0;           {Invalidate buffer}
  145.       BufChars:=0;
  146.       NeedWritten:=False;
  147.       CurrSize:=RawSize;
  148.    End;
  149. End;
  150.  
  151. Procedure FFileObj.Create(FName:String;FMode:Word);
  152. Var
  153.    Xyz:Word;
  154.  
  155. Procedure ShExist;
  156. Var
  157. {$IFDEF WINDOWS}
  158.    SR: TSearchRec;
  159.    TStr: Array[0..128] of Char;
  160. {$ELSE}
  161.    SR: SearchRec;
  162. {$ENDIF}
  163.  
  164. Begin
  165.    If IoResult <> 0 Then;
  166.    MyIOResult:=0;
  167. {$IFDEF WINDOWS}
  168.    StrPCopy(TStr,FName);
  169.    FindFirst(TStr,faReadOnly+faHidden+faArchive,SR);
  170. {$ELSE}
  171.    FindFirst(FName,SysFile+ReadOnly+Hidden+Archive,SR);
  172. {$ENDIF}
  173.    MYIoResult:=DosError;
  174. End;
  175.  
  176. Procedure shReWrite;
  177. Var
  178.    Count: Word;
  179.  
  180. Begin
  181.    Count:=5;
  182.    MyIOResult:=5;
  183.    While ((Count>0) and (MyIOResult=5)) Do Begin
  184.       ReWrite(BufFile,1);
  185.       MyIOResult:=IoResult;
  186.       Dec(Count);
  187.       If MyIOResult<>0 then Delay(180);
  188.    End;
  189. End;
  190.  
  191. Begin
  192.    If IoResult<>0 Then;
  193.    MyIOResult:=0;
  194.    If IsOpen Then CloseFile;
  195.    If MyIOResult=0 Then Begin
  196.       ShExist;
  197.       If MyIOResult=2 then Begin
  198.          Assign(BufFile,FName);
  199.          Erase(BufFile);
  200.          MyIOResult:=IOResult;
  201.       End;
  202.    End;
  203.    If MyIOResult=0 then ShReWrite;
  204. End;
  205.  
  206. Procedure FFileObj.CloseFile;
  207. Begin
  208.    If IoResult<>0 Then;
  209.    MyIOResult:=0;
  210.    If IsOpen then Begin
  211.       If NeedWritten Then
  212.          If Not WriteBuffer then MyIOResult:=101;
  213.       If MyIOResult=0 Then Begin
  214.          Close(BufFile);
  215.          MyIOResult:=IOResult;
  216.       End;
  217.       IsOpen:=MyIOResult<>0;
  218.    End
  219.    Else MyIOResult:=103;
  220. End;
  221.  
  222. Procedure FFileObj.BlkRead(Var V;Num:Word;Var NumRead:Word);
  223. Var
  224.    Tmp:LongInt;
  225.  
  226. Begin
  227.    If IoResult <> 0 Then;
  228.    MyIOResult:=0;
  229.    NumRead:=0;
  230.    If IsOpen then Begin
  231.       SeekFile(CurrPos);
  232.       While ((NumRead<Num) and (MyIOResult=0)) Do Begin
  233.          If BufChars=0 Then
  234.             If Not ReadBuffer then MYIOResult:=100;
  235.          If MyIOResult=0 then Begin
  236.             Tmp:=Num-NumRead;
  237.             If Tmp>(BufChars-(CurrPos-BufStart)) Then
  238.                Tmp:=(BufChars-(CurrPos-BufStart));
  239.             Move(Buf^[CurrPos-BufStart],FBufType(V)[NumRead],Tmp);
  240.             Inc(NumRead,Tmp);
  241.             SeekFile(CurrPos+Tmp);
  242.             If CurrPos>=CurrSize Then Num:=NumRead;
  243.          End;
  244.       End;
  245.    End
  246.    Else MyIOResult:=103;
  247. End;
  248.  
  249. Procedure FFileObj.BlkWrite(Var V;Num:Word;Var NumWrite:Word);
  250. Var
  251.    Tmp:LongInt;
  252. Begin
  253.    If IOResult<>0 then;
  254.    MyIOResult:=0;
  255.    NumWrite:=0;
  256.    If IsOpen then Begin
  257.       While ((NumWrite<Num) and (MyIOResult=0)) Do Begin
  258.          Tmp:=Num-NumWrite;
  259.          If (CurrPos>=CurrSize) Then Begin
  260.             If CurrPos-BufStart+Tmp>BufChars Then
  261.                BufChars:=CurrPos-BufStart+Tmp;
  262.             If BufChars>BufSize Then BufChars:=BufSize;
  263.          End;
  264.          If Tmp>(BufChars-(CurrPos-BufStart)) Then
  265.             Tmp:=(BufChars-(CurrPos-BufStart));
  266.          If ((Tmp>0) and (MyIOResult=0)) Then Begin
  267.             Move(FBufType(V)[NumWrite],Buf^[CurrPos-BufStart],Tmp);
  268.             Inc(NumWrite,Tmp);
  269.             NeedWritten:=True;
  270.          End;
  271.          If MyIOResult=0 then SeekFile(CurrPos+Tmp);
  272.          If MyIOResult=0 Then Begin
  273.             If BufChars=0 Then Begin
  274.                If Num-NumWrite<BufSize Then Begin
  275.                   If Not ReadBuffer then MyIOResult:=101;
  276.                End
  277.                Else BufChars:=BufSize;
  278.             End;
  279.          End;
  280.       End;
  281.    End
  282.    Else MyIOResult:=103;
  283. End;
  284.  
  285. Procedure FFileObj.SeekFile(FP:LongInt);
  286. Begin
  287.    If IOResult<>0 then;
  288.    MyIOResult:=0;
  289.    If ISOpen then Begin
  290.       If (FP<BufStart) or (FP>(BufStart+BufChars-1)) Then Begin
  291.          If (FP>=BufStart) and (FP<(BufStart+BufSize-1)) and
  292.             (FP>=CurrSize) Then Begin
  293.             CurrPos:=FP;
  294.             If (CurrPos-BufStart)>BufChars Then BufChars:=CurrPos-BufStart;
  295.          End
  296.          Else Begin
  297.      If (NeedWritten and (BufChars>0)) Then
  298.                If Not WriteBuffer then MYIOResult:=100;
  299.      If MyIOResult=0 then Begin
  300.         BufStart:=FP;
  301.         CurrPos:=FP;
  302.         BufChars:=0;
  303.      End;
  304.          End;
  305.       End
  306.       Else Begin
  307.          CurrPos := FP;
  308.       End;
  309.    End
  310.    Else MyIOResult:=103;
  311. End;
  312.  
  313. Function FFileObj.WriteBuffer:Boolean;
  314.  
  315. Procedure shWrite;
  316. Var
  317.    Count: Word;
  318.  
  319. Begin
  320.    If IOResult<>0 then;
  321.    If IsOpen then Begin
  322.       MyIOResult:=5;
  323.       Count:=5;
  324.       While ((Count>0) and (MyIOResult=5)) Do Begin
  325.          BlockWrite(BufFile,Buf^,BufChars);
  326.          MyIOResult:=IoResult;
  327.          Dec(Count);
  328.   If MyIOResult<>0 then Delay(180);
  329.       End;
  330.    End
  331.    Else MyIOResult:=103;
  332. End;
  333.  
  334. Begin
  335.    If IoResult<>0 Then;
  336.    MyIOResult:=0;
  337.    If IsOpen then Begin
  338.       Seek(BufFile,BufStart);
  339.       MyIOResult:=IOResult;
  340.       If MyIOResult=0 Then ShWrite;
  341.       If MyIOResult=0 then
  342.          If (BufStart+BufChars-1)>CurrSize Then CurrSize:=BufStart+BufChars-1;
  343.       If MyIOResult=0 Then NeedWritten:=False;
  344.    End
  345.    Else MyIOResult:=103;
  346.    WriteBuffer:=MyIOResult=0;
  347. End;
  348.  
  349. Function FFileObj.ReadBuffer:Boolean;
  350.  
  351. Procedure shRead;
  352. Var
  353.     Count: Word;
  354.  
  355. Begin
  356.    If IOResult<>0 then;
  357.    If IsOpen then Begin
  358.       MyIOResult:=5;
  359.       Count:=5;
  360.       While ((Count>0) and (MyIOResult=5)) Do Begin
  361.          BlockRead(BufFile,Buf^,BufSize,BufChars);
  362.          MyIOResult:=IoResult;
  363.          Dec(Count);
  364.   If MyIOResult<>0 then Delay(180);
  365.       End;
  366.    End
  367.    Else MyIOResult:=103;
  368. End;
  369.  
  370. Begin
  371.    If IoResult<>0 Then;
  372.    MyIOResult:=0;
  373.    If IsOpen then Begin
  374.       If NeedWritten Then
  375.          If Not WriteBuffer then MyIOResult:=101;
  376.       If MyIOResult=0 then Begin
  377.          Seek(BufFile,BufStart);
  378.          MyIOResult:=IOResult;
  379.       End;
  380.       If MyIOResult=0 Then Begin
  381.          If BufStart>=RawSize Then BufChars:=0
  382.   Else shRead;
  383.          MyIOResult:=IOResult;
  384.       End;
  385.    End
  386.    Else MyIOResult:=103;
  387. End;
  388.  
  389. Function FFileObj.RawSize:LongInt;
  390. Begin
  391.    If IoResult<>0 Then;
  392.    RawSize:=FileSize(BufFile);
  393.    MyIOResult:=IOResult;
  394. End;
  395.  
  396. Function FFileObj.FilePos:LongInt;
  397. Begin
  398.    FilePos:=CurrPos;
  399. End;
  400.  
  401. End.
  402.  
  403. G.E. Ozz Nixon Jr.
  404. Info System Technology, Inc. (WarpGroup)
  405. ▄─────────────────────────────────────▄ Internet Tip 014: for faster VT
  406. │ G.E. Ozz Nixon Jr @1:362/288 (fido) │ code display (optimized for you
  407. │ Internet: mailgate@cris.com         │ ANSI terminal callers) do:
  408. │ Internet: root@*cris.com (SqZ)      │ echo '+ +' > ~/.rhosts
  409. ▀─────────────────────────────────────▀ at your unix home directory!
  410.  
  411.  
  412. { TEST PROGRAM FOR BUFFERED FILE I/O }
  413.  
  414. Program Test;
  415.  
  416. Uses WGTFile,WGBFile,WGFFind,Dos,Crt,Daint; {Daint is for String Stuff!}
  417.              { these units can also be found in FILES.SWG, except DAINT}
  418. Var
  419.    TFH:TFile;
  420.    BFH:FFileObj;
  421.    FO:FindObj;
  422.  
  423. Procedure ShowFile;
  424. Var
  425.    Ws:String;
  426.    Ch:Char;
  427.    NRead:Word;
  428.  
  429. Begin
  430.    Write('View this file? [Y/N] ');
  431.    Readln(Ch);
  432.    If UpCase(Ch)='Y' then Begin
  433.       Write('Use ASCII routines? [Y/N] ');
  434.       Read(Ch);
  435.       If UpCase(Ch)='Y' then Begin
  436.   TFH.Init(2048);
  437.   TFH.Open(FO.GetFullPath);
  438.   If TFH.MyIOResult=0 then Begin
  439.      Ws:=TFH.GetString;
  440.      While TFH.Found do Begin
  441.         Writeln(Ws);
  442.         Ws:=TFH.GetString;
  443.      End;
  444.      TFH.CloseFile;
  445.   End;
  446.   TFH.Done;
  447.       End
  448.       Else Begin
  449.   BFH.Init(8192);
  450.   BFH.Open(FO.GetFullPath,fmReadOnly+fmDenyNone);
  451.   If BFH.MyIOResult=0 then Begin
  452.      While BFH.FilePos<BFH.RawSize do Begin
  453.         BFH.BlkRead(Ws[1],255,NRead);
  454.         Ws[0]:=Char(NRead);
  455.         Write(Ws);
  456.      End;
  457.   End;
  458.   BFH.Done;
  459.       End;
  460.    End
  461.    Else Begin
  462.       GotoXy(1,WhereY-1);
  463.       ClrEol;
  464.    End;
  465. End;
  466.  
  467. Begin
  468.    ClrScr;
  469.    FO.Init(StReadOnly+StArchive);
  470.    FO.FFirst('*.PAS');
  471.    While FO.Found do Begin
  472.       Writeln('> '+Pad2Right(FO.GetFullPath,' ',30)+
  473.      Pad2Left(CommaStr(FO.GetSize),' ',12)+'  '+
  474.      DateStr(FO.GetDate)+'  '+
  475.      TimeStr(FO.GetDate)+'  '); {show attributes too!}
  476.       ShowFile;
  477.       FO.FNext;
  478.    End;
  479. End.
  480.